class User {
  String name;
  int age;
  User(
    this.name,
    this.age,
  );
}

bool isValidEmailAddress(string) {
  return string is EmailAddress;
}

Iterable<EmailAddress> parseEmailAddresses(Iterable<String> strings) {
  return strings.map((e) => EmailAddress(e));
}

bool anyInvalidEmailAddress(Iterable<EmailAddress> emails) {
  return emails.any((element) => isValidEmailAddress(element));
}

Iterable<EmailAddress> validEmailAddresses(Iterable<EmailAddress> emails) {
  return emails.where((element) => isValidEmailAddress(element));
}

class EmailAddress {
  final String address;

  EmailAddress(this.address);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is EmailAddress && address == other.address;

  @override
  int get hashCode => address.hashCode;

  @override
  String toString() {
    return 'EmailAddress{address: $address}';
  }
}

main(List<String> args) {
  Iterable<int> iterable = [1, 2, 3];
  List<int> list = [11, 22, 33];
  int value = list[1];
  int value2 = iterable.elementAt(1);
  for (var element in list) {
    print(element);
  }
  // 首尾
  print('The first element is ${iterable.first}');
  print('The last element is ${list.last}');
  // 满足条件的第一个 firstWhere
  int element = iterable.firstWhere((element) => element > 5, orElse: () => 0);
  print('$element');

  // singleWhere多于一个或没有抛出StateError
  List<String> list2 = ["Mddaee", "ddd", "aaa"];
  List<String> list3 = ["addaee", "ddd", "aaa"];
  String singleWhere(Iterable<String> items) {
    return items.singleWhere(
        (element) => element.contains('a') && element.startsWith('M'),
        orElse: () => 'none');
  }

  print(singleWhere(list2));
  print(singleWhere(list3));

  // any() and every()
  const items = ['Salad', 'Popcorn', 'Toast'];
  if (items.any((element) => element.contains('a'))) {
    print('At least one element contains "a"');
  }
  if (items.every((element) => element.length >= 5)) {
    print('All elements have length >= 5');
  }
  bool anyUserUnder18(Iterable<User> users) {
    return users.any((element) => element.age < 18);
  }

  bool everyUserOver13(Iterable<User> users) {
    return users.every((element) => element.age > 13);
  }

  // filter where()查询全部true takeWhile()取true之前的集合 skipWhile()取true及之后的集合
  // number.isEven isNegative
  var evenNumbers = list.where((number) => number.isEven);
  print(evenNumbers);

  const numbers = [1, 3, -2, 0, 4, 5];

  var numbersUntilZero = numbers.takeWhile((number) => number != 0);
  print('Numbers until 0: $numbersUntilZero'); // (1, 3, -2)

  var numbersStartingAtZero = numbers.skipWhile((number) => number != 0);
  print('Numbers starting at 0: $numbersStartingAtZero'); // (0, 4, 5)

  Iterable<User> filterOutUnder21(Iterable<User> users) {
    return users.where((element) => element.age >= 21);
  }

  Iterable<User> findShortNamed(Iterable<User> users) {
    return users.where((element) => element.name.length <= 3);
  }

  // map()
  Iterable<int> output = numbers.map((number) => number * 10);
  Iterable<String> getNameAndAges(Iterable<User> users) {
    return users.map((element) => '${element.name} is ${element.age}');
  }
}
